package vampirism.core.client;

import com.esotericsoftware.kryonet.Client;
import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.Listener;
import com.esotericsoftware.kryonet.Listener.ThreadedListener;
import vampirism.core.shared.Network;
import vampirism.core.shared.Network.*;

import java.io.IOException;

public class ClientSide implements Runnable{
	
		public MainGame main;
        public Client client;
        
        public boolean haveStartedGame = false;
        
        public ClientSide(MainGame mainGame){
        	this.main = mainGame;
        }
        
        //Sending Login/Registration request to server
        public void simulateLogin(String email, String pass){
            
            Login login = new Login();
            login.email = email;
            login.pass = pass;
            client.sendTCP(login);
        }
        
        //Sending new character creation request to server
        public void simulateCreatePlayer(String name, byte type){
        	CreatePlayer createPlayer = new CreatePlayer();
        	createPlayer.name = name;
        	createPlayer.type = type;
        	client.sendTCP(createPlayer);
        }
        
        //Sending new character selection request to server (after pressing play)
		public void simulateSelect(int chosen) {
			SelectPlayer selectPlayer = new SelectPlayer();
			selectPlayer.accountPlayerNum = chosen;
			client.sendTCP(selectPlayer);
		}
		
		//Sending new movement packet to server
		public void simulateMove(boolean[] moving) {
			Move move = new Move();
			move.moving = moving;
			move.syncX = main.myPlayer.pos.x;
			move.syncY = main.myPlayer.pos.y;
			client.sendTCP(move);
		}
		
		//Sending new shoot packet to server
		public void simulateShoot(float rotation) {
			Shoot shoot = new Shoot();
			shoot.rotation = rotation;
			client.sendTCP(shoot);
		}

		@Override
        public void run() {
			
                client = new Client(6112,6112);
                client.start();

                
                Network.register(client);


                // ThreadedListener runs the listener methods on a different thread.
                client.addListener(new ThreadedListener(new Listener() {
                        public void connected (Connection connection) {
                        	System.out.println("#CLIENT: connected!");
                        }

                        public void received (Connection connection, Object object) {
                        	
                        	//System.out.println("#CLIENT: received packet: "+object.toString());
                        	
                        	if(object instanceof LoginResult){
                        		LoginResult resultPacket = (LoginResult)object;
                        		
                        		if(resultPacket.result.equals(LoginResultType.INCORRECT_PASS)){
                        			main.showInfo("The password you entered is incorrect.");
                        		}else
                             	if(resultPacket.result.equals(LoginResultType.INVALID_EMAIL)){
                            		main.showInfo("Please enter a valid email.");
                            	}else
                                if(resultPacket.result.equals(LoginResultType.INVALID_PASS)){
                                	main.showInfo("Please enter a valid password (3-50 characters)");
                                }else{
                                	main.menuLogin.confirmButton.setDisabled(false);
                                	
                                	if(resultPacket.result.equals(LoginResultType.REG_SUCCESS)){
                                		main.changeMenu(1);
                                	}else
                                    if(resultPacket.result.equals(LoginResultType.LOGIN_SUCCESS)){
                                    	main.myPlayers = resultPacket.myPlayers;
                                    	main.changeMenu(2);
                                    }
                                }
                        	}else                        	
                        	if(object instanceof CreatePlayerResult){
                        		CreatePlayerResult resultPacket = (CreatePlayerResult)object;
                        		
                        		if(resultPacket.result.equals(CreatePlayerResultType.INVALID_NAME)){
                        			main.showInfo("Please enter a valid name. (3-12 letters or numbers)");
                        		}else
                        		if(resultPacket.result.equals(CreatePlayerResultType.INVALID_TYPE)){
                        			main.showInfo("Please choose character class.");
                        		}else
                        		if(resultPacket.result.equals(CreatePlayerResultType.NAME_ALREADY_EXISTS)){
                        			main.showInfo("Name already exists.");
                        		}else
                        		if(resultPacket.result.equals(CreatePlayerResultType.TOO_MANY_CHARACTERS)){
                        			main.showInfo("You already have the maximum number of characters.");
                        		}else
                        		if(resultPacket.result.equals(CreatePlayerResultType.SUCCESS)){
                        			main.myPlayers = resultPacket.myPlayers;
                        			main.changeMenu(2);
                        		}
                        	}else                        	
                            if(object instanceof SelectPlayerResult){
                            	SelectPlayerResult resultPacket = (SelectPlayerResult)object;
                            	
                            	if(resultPacket.result.equals(SelectPlayerResultType.INVALID_ID)){
                        			main.showInfo("Please select a valid character.");
                        		}else
                            	if(resultPacket.result.equals(SelectPlayerResultType.SUCCESS)){
                            		
                        			main.players = resultPacket.allPlayers;
                        			main.clientUpdater.players = main.players;
                        			main.clientUpdater.bullets = main.bullets;
                        			
                        			int myPlayerIndex = resultPacket.myPlayerIndex;
                        			
                        			haveStartedGame = true;
                        			
                        			if(resultPacket.gameLaunched)main.clientUpdater.enableMap();
                        			
                        			main.myPlayer = resultPacket.allPlayers.get(myPlayerIndex);

                        			main.changeMenu(3);
                        		}
                            }else                        	
                            if(object instanceof AddPlayer){
                            	if(haveStartedGame){
	                            	AddPlayer addPlayerPacket = (AddPlayer)object;
	                            	main.players.add(addPlayerPacket.newPlayer);
                            	}
                            }else                      	
                            if(object instanceof UpdatePlayer){//Update always contains info about OTHER accounts (not this account)
                                	
                            	if(haveStartedGame){
	                            	UpdatePlayer updatePacket = (UpdatePlayer)object;
	                                	
	                                //Set the movement direction of the specific player (can't be my player - prevents jagged movement)
	                                main.players.get(updatePacket.index).moving = updatePacket.moving;
	                                	
	                                //Update given player position (but not my player position)
	                                if(updatePacket.index!=main.myPlayer.index){
	                                	main.players.get(updatePacket.index).pos.x = updatePacket.syncX;
	                                	main.players.get(updatePacket.index).pos.y = updatePacket.syncY;
	                                }
                            	}
                            }else
                            if(object instanceof AddBullet){
                            	AddBullet addBulletPacket = (AddBullet)object;
                            	main.bullets.add(addBulletPacket.bullet);
                            }else
                            if(object instanceof Hit){
                            	if(haveStartedGame){
                            		Hit hit = (Hit)object;
                            	
                            		main.clientUpdater.hit(hit.sourceId, hit.targetId, hit.damage);
                            	}
                            }else                       	
                            if(object instanceof RemoveBody){
                            	
                            	if(haveStartedGame){
                            		RemoveBody packet = (RemoveBody)object;
                            		main.clientUpdater.removeBody(packet.bodyIndex);
                            	}
                            }else
                        	if(object instanceof GainExp){
                             	
                             	if(haveStartedGame){
                             		GainExp packet = (GainExp)object;
                             		main.clientUpdater.gainExp(packet.bodyIndex, packet.amount);
                             	}
                            }else
                            if(object instanceof LaunchGame){
                                 	
                                 if(haveStartedGame){
                                	 LaunchGame launchGame = (LaunchGame)object;
                                	 
                                 	main.clientUpdater.launchGame(launchGame.alphaId);
                                 }
                            }
                        }

                        public void disconnected (Connection connection) {
                        	System.out.println("disconnected :(");
                                //System.exit(0);
                        }
                }));

                try {
                		// Connect the client to server using specific address and port
                        client.connect(6112, "83.99.171.130", Network.port);
                        // Server communication after connection can go here, or in Listener#connected().
                } catch (IOException ex) {
                        ex.printStackTrace();
                }
                
        }



}
